﻿#ifndef _MAINDRAWSCENE_H_INCLUDE_
#define _MAINDRAWSCENE_H_INCLUDE_

#include "common.h"
#include "singleton.h"
#include <map>
#include <mutex>
#include "ft2build.h"
#include FT_FREETYPE_H
#include "glm/glm.hpp"
#include "nodemanager/wbasenode.h"

struct TextureInfo
{
    TextureInfo()
        : id(0),width(0),height(0) {}
    TextureInfo(unsigned int pid,int pwidth,int pheight)
        : id(pid),width(pwidth),height(pheight) {}

    unsigned int id;
    int width;
    int height;
};

// OpenGL 上下文管理类
class MyGLContext
{
public:
    MyGLContext(wxGLCanvas* canvas) : m_canvas(canvas) {
        m_glContext = new wxGLContext(m_canvas);
    }

    ~MyGLContext() {
        delete m_glContext;
    }

    void SetCurrent() {
        m_canvas->SetCurrent(*m_glContext);
    }

private:
    wxGLContext* m_glContext;
    wxGLCanvas* m_canvas;
};

class maindrawscene : public Singleton<maindrawscene>,
                      public wxGLCanvas
{
public:
    maindrawscene(wxWindow* parent);
    ~maindrawscene();

    std::mutex* getSceneLock(void) { return &m_SceneMutex; }
    /// 得到文本显示长度
    wxRealPoint getTextLength(wxString text,float scale=1.0f);
    /// 从文件中导入图片作为纹理
    unsigned int LoadTextureFromFile(const char* filePath, bool generateMipmaps);

    /// 画点
    void DrawPoint(wxRealPoint pos, wxColour color=wxColour(), float size=1.0f);
    /// 画线
    void DrawLine(wxRealPoint startpos,wxRealPoint endpos,
                  float borderWidth = 1.0f,
                  wxColour color=wxColour(),
                  float rotationDegrees = 0.0f);
    /// 绘制文字
    void DrawText1(const char* ttext,
                    wxRealPoint pos,
                    float scale=1.0f,
                    wxColour color=wxColour(),
                    float rotationDegrees = 0.0f);
    /// 绘制文字
    void DrawText2(const char* ttext,
                    wxRect displayRect,    // 文本显示区域（包含位置和大小）
                    float scale,
                    wxColour color,
                    float rotationDegrees = 0.0f,
                    bool enableClipping = true,
                    bool centerHorizontally = true,  // 水平居中
                    bool centerVertically = true);     // 垂直居中
    // 绘制文字
    void DrawText3(const char* ttext,
                    wxRealPoint pos,
                    wxColour color,
                    float rotationDegrees,
                    int alignment=0,  // 默认左对齐
                    float offset = 0.0f);                           // 默认无偏移
    void DrawText4(const char* ttext,
                    wxRealPoint pos,
                    wxColour color,
                    float rotationDegrees,
                   int alignment=0,
                   float scale=1.0f);

    /// 画圆
    void DrawCircle(wxRealPoint pos, float radius,
                    int segments = 32,
                    wxColour fillColor=wxColour(),
                    wxColour borderColor=wxColour(),
                    float borderWidth = 1.0f,
                    float scale = 1.0f);
    /// 画矩形
    void DrawRectangle(wxRect rect,wxColour color,
                       float angle=0.0f,
                       wxRealPoint rotationAnchor=wxRealPoint(0.0f,0.0f),
                       float scaleX=1.0f, float scaleY=1.0f,
                       bool filled=true, wxColour borderColor=wxColour(),float borderWidth=0.0f);
    /// 画纹理
    void DrawTexture(unsigned int textureid,
                       wxRealPoint position,
                       wxSize size = wxDefaultSize,
                       float rotation = 0.0f,
                       wxColour color = wxColour(255, 255, 255, 255),
                       wxRect uvRect = wxRect(0, 0, 0, 0));

protected:
    void OnPaint(wxPaintEvent& event);
    void OnSize(wxSizeEvent& event);
    void OnUpdateTimer(wxTimerEvent& event);
    void OnMouseEvent(wxMouseEvent& event);
    void OnOpenFileMenu(wxCommandEvent& event);
    void OnSystemScriptTimer(wxTimerEvent& event);

private:
    void InitGL(void);
    void SetupTopLeftOrtho();
    // 初始化 FreeType
    bool InitializeFreeType();
    // 卸载freetype
    void shutdownFreeType();
    // 加载所有的字体
    void LoadAllCharacter(void);
    bool LoadCharacter(FT_ULong charcode);
    wxString GetDecodedText(const char* text);
    void deleteAllTextures(void);
    TextureInfo* isExistTexture(unsigned int texid);

private:
    wxTimer* m_updatetimer,*m_scriptTimer;
    MyGLContext* m_glContext;
    bool m_initialized;

    std::mutex m_SceneMutex;
    wxMenu* m_ContextMenu,*m_NodeContextMenu;
    wxMenuItem *m_Nodeitem;
    std::map<wxMenuItem*,wxArtID> m_ContextMenuItemArts;
    std::unordered_map<std::string, wxString> m_textCache;
    std::unordered_map<wxString, TextureInfo> m_textures;

    // 字符结构体
    struct Character {
        GLuint textureID;    // 字形纹理ID
        glm::ivec2 size;     // 字形大小
        glm::ivec2 bearing;  // 从基准线到字形左部/顶部的偏移值
        FT_Pos advance;      // 距下一个字形的距离
    };

    FT_Library m_ft;                 // FreeType 库
    FT_Face m_face;                  // 字体面
    std::map<FT_ULong, Character> m_characters;  // 字符缓存
    bool m_freetypeInitSuccessed;     // freetype是否初始成功
};

#endif // MAINDRAWSCENE_H
